#include <stdio.h>

typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len) {
    for (size_t i = 0; i < len; i++) {
        printf(" %.2x", start[i]);
    }
    printf("\n");
}
void show_int(int x) {
    show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x) {
    show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void *x) {
    show_bytes((byte_pointer) &x, sizeof(void *));
}


void test_show_bytes(int val) {
    int ival = val;
    float fval = (float) val;
    int *pval = &ival;
    printf("Integer value: ");
    show_int(ival);
    printf("Float value:   ");
    show_float(fval);
    printf("Pointer value: ");
    show_pointer(pval);

    printf("String value: ");
    show_bytes((byte_pointer) "Hello", 6);
}

int main() {
    int x = 0x12345678;
    float y = 123.456;
    int *p = &x;

    printf("x: ");
    show_int(x);
    printf("y: ");
    show_float(y);
    printf("p: ");
    show_pointer(p);

    printf("Testing show_bytes with integer value 12345\n");
    test_show_bytes(12345);


    return 0;
}
// Compile with: gcc -o show-bytes show-bytes.c
// Run with: ./show-bytes
// Output will show the byte representation of the integer, float, and pointer
// in hexadecimal format.
// The output will depend on the architecture (endianness) of the machine
// where the code is executed. For example, on a little-endian machine,
// the output for the integer 0x12345678 would be:
// 78 56 34 12
// and for the float 123.456, it would show the byte representation of that
// float value in memory.
// The pointer output will show the address of the integer variable in memory,
// which will also depend on the machine's architecture (32-bit or 64-bit).
// The output will look something like this:
// x: 78 56 34 12
// y: 00 00 00 00 00 00 f6 42
// p: 7ffeefbff5c8
// ------------------------------------
// Note: The actual byte values may vary based on the system architecture
// and the compiler used. The example above is for illustrative purposes only.
// The output will be in hexadecimal format, with each byte represented
// as two hexadecimal digits. The address of the pointer will be shown in
// hexadecimal as well, and it will vary each time the program is run
// due to the nature of memory allocation in C.
// The program demonstrates how to interpret the binary representation
// of different data types in C, including integers, floats, and pointers.
// It is important to note that the output may differ based on the
// endianness of the machine (little-endian vs big-endian) and the
// architecture (32-bit vs 64-bit). The program is a simple example
// of how to visualize the memory representation of different data types
// in C, which can be useful for understanding how data is stored
// and manipulated in memory. It can also help in debugging and
// understanding low-level programming concepts.
// The program can be extended to include other data types such as
// doubles, structs, and arrays, and can be modified to show the
// representation of these types in memory as well. This can provide
// further insights into how data is represented and manipulated
// in C, and can help in understanding the underlying principles
// of computer architecture and programming.